package cn.cyh.queue_service.mq.consumer;

import cn.cyh.queue_service.config.RabbitMQConfig;
import cn.cyh.queue_service.mq.event.StatsUpdateEvent;
import cn.cyh.queue_service.service.CacheService;
import cn.cyh.queue_service.service.StatisticsService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 统计数据更新事件消费者
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class StatsUpdateEventConsumer {

    private final StatisticsService statisticsService;
    private final CacheService cacheService;
    private final ObjectMapper objectMapper;
    
    /**
     * 处理统计数据更新事件
     *
     * @param message 消息
     * @param channel 通道
     */
    @RabbitListener(queues = RabbitMQConfig.QUEUE_STATISTICS_UPDATE)
    public void handleStatsUpdateEvent(Message message, Channel channel) throws IOException {
        try {
            // 获取消息内容
            String content = new String(message.getBody());
            StatsUpdateEvent event = objectMapper.readValue(content, StatsUpdateEvent.class);
            
            log.info("收到统计数据更新事件: 类型: {}", event.getStatsType());
            
            // 根据统计类型执行不同的更新逻辑
            switch (event.getStatsType()) {
                case "DAILY":
                    handleDailyStats(event);
                    break;
                case "WINDOW":
                    handleWindowStats(event);
                    break;
                case "SERVICE_TYPE":
                    handleServiceTypeStats(event);
                    break;
                case "STAFF":
                    handleStaffStats(event);
                    break;
                default:
                    log.warn("未知的统计类型: {}", event.getStatsType());
            }
            
            // 确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            log.error("处理统计数据更新事件失败", e);
            
            // 拒绝消息并重新入队
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
        }
    }
    
    /**
     * 处理每日统计数据
     *
     * @param event 统计事件
     */
    private void handleDailyStats(StatsUpdateEvent event) {
        // 构建缓存键
        String cacheKey = "stats:daily:" + event.getStatsDate();
        
        // 获取并更新缓存中的统计数据
        Map<String, Object> currentStats = cacheService.get(cacheKey);
        if (currentStats == null) {
            // 缓存中没有数据，直接使用事件中的数据
            cacheService.set(cacheKey, event.getMetrics(), 7, TimeUnit.DAYS);
        } else {
            // 缓存中有数据，合并更新
            currentStats.putAll(event.getMetrics());
            cacheService.set(cacheKey, currentStats, 7, TimeUnit.DAYS);
        }
        
        // 更新数据库统计信息
        statisticsService.updateDailyStats(event.getStatsDate(), event.getMetrics());
    }
    
    /**
     * 处理窗口统计数据
     *
     * @param event 统计事件
     */
    private void handleWindowStats(StatsUpdateEvent event) {
        // 构建缓存键
        String cacheKey = "stats:window:" + event.getWindowId() + ":" + event.getStatsDate();
        
        // 获取并更新缓存中的统计数据
        Map<String, Object> currentStats = cacheService.get(cacheKey);
        if (currentStats == null) {
            // 缓存中没有数据，直接使用事件中的数据
            cacheService.set(cacheKey, event.getMetrics(), 7, TimeUnit.DAYS);
        } else {
            // 缓存中有数据，合并更新
            currentStats.putAll(event.getMetrics());
            cacheService.set(cacheKey, currentStats, 7, TimeUnit.DAYS);
        }
        
        // 更新数据库统计信息
        statisticsService.updateWindowStats(event.getWindowId(), event.getStatsDate(), event.getMetrics());
    }
    
    /**
     * 处理业务类型统计数据
     *
     * @param event 统计事件
     */
    private void handleServiceTypeStats(StatsUpdateEvent event) {
        // 构建缓存键
        String cacheKey = "stats:service:" + event.getServiceTypeId() + ":" + event.getStatsDate();
        
        // 获取并更新缓存中的统计数据
        Map<String, Object> currentStats = cacheService.get(cacheKey);
        if (currentStats == null) {
            // 缓存中没有数据，直接使用事件中的数据
            cacheService.set(cacheKey, event.getMetrics(), 7, TimeUnit.DAYS);
        } else {
            // 缓存中有数据，合并更新
            currentStats.putAll(event.getMetrics());
            cacheService.set(cacheKey, currentStats, 7, TimeUnit.DAYS);
        }
        
        // 更新数据库统计信息
        statisticsService.updateServiceTypeStats(event.getServiceTypeId(), event.getStatsDate(), event.getMetrics());
    }
    
    /**
     * 处理业务员统计数据
     *
     * @param event 统计事件
     */
    private void handleStaffStats(StatsUpdateEvent event) {
        // 构建缓存键
        String cacheKey = "stats:staff:" + event.getStaffId() + ":" + event.getStatsDate();
        
        // 获取并更新缓存中的统计数据
        Map<String, Object> currentStats = cacheService.get(cacheKey);
        if (currentStats == null) {
            // 缓存中没有数据，直接使用事件中的数据
            cacheService.set(cacheKey, event.getMetrics(), 7, TimeUnit.DAYS);
        } else {
            // 缓存中有数据，合并更新
            currentStats.putAll(event.getMetrics());
            cacheService.set(cacheKey, currentStats, 7, TimeUnit.DAYS);
        }
        
        // 更新数据库统计信息
        statisticsService.updateStaffStats(event.getStaffId(), event.getStatsDate(), event.getMetrics());
    }
} 